package plus.easydo.jdbc.base.sql.utils;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import plus.easydo.core.exception.ExceptionFactory;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

/**
 * 类辅助
 *
 * @author yuzhanfeng
 */
public class ClassUtils {

    /** 日志对象 */
    private static final Logger LOG = LoggerFactory.getLogger(ClassUtils.class);

    /**
     * Map keyed by class containing CachedIntrospectionResults.
     * Needs to be a WeakHashMap with WeakReferences as values to allow
     * for proper garbage collection in case of multiple class loaders.
     */
    private static final Map<Class<? extends Object>, BeanInfo> CLASS_CACHE = Collections
            .synchronizedMap(new WeakHashMap<>());

    /**
     * 获取类本身的BeanInfo，不包含父类属性
     *
     * @param clazz clazz
     * @return java.beans.BeanInfo
     * @author laoyu
     */
    public static BeanInfo getSelfBeanInfo(Class<?> clazz) {
        try {
            BeanInfo beanInfo;
            if (CLASS_CACHE.get(clazz) == null) {
                beanInfo = Introspector.getBeanInfo(clazz, clazz.getSuperclass());
                CLASS_CACHE.put(clazz, beanInfo);
                // Immediately remove class from Introspector cache, to allow for proper
                // garbage collection on class loader shutdown - we cache it here anyway,
                // in a GC-friendly manner. In contrast to CachedIntrospectionResults,
                // Introspector does not use WeakReferences as values of its WeakHashMap!
                Class<?> classToFlush = clazz;
                do {
                    Introspector.flushFromCaches(classToFlush);
                    classToFlush = classToFlush.getSuperclass();
                } while (classToFlush != null);
            } else {
                beanInfo = CLASS_CACHE.get(clazz);
            }
            return beanInfo;
        } catch (Exception e) {
            LOG.error("获取BeanInfo失败", e);
            throw ExceptionFactory.baseException(e.getMessage());
        }
    }

    /**
     * 初始化实例
     *
     * @param clazz clazz
     * @return java.lang.Object
     * @author laoyu
     */
    public static Object newInstance(Class<?> clazz) {
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            LOG.error("根据class创建实例失败", e);
            throw ExceptionFactory.baseException(e.getMessage());
        }
    }
}


